#pragma once

#include "Shape.hpp"

namespace Geometry {

/*
  Plane Equation:
  * (p-a)*((b-a)x(c-a)) = 0

  * according to the equation, we can get full-blown cartesian representation
  * for this by the determinant:
  * | x−xa   y-ya  z-za |
  * | xb−xa yb-ya zb-za | = 0
  * | xc-xa yc-ya zc-za |

  * p, a, b, c is a vector in the same plane
*/
class Plane : public Shape {
public:
  /*
    Construct a plane base on three points
    @param a plane origin
    @param b a point in the plane
    @param c a point in the plane
  */
  Plane(glm::vec3 a, glm::vec3 b, glm::vec3 c);

  /*
   * Default Create a x-z plane
   */
  Plane();

  void SetOrigin(glm::vec3 o);
  void SetOtherPoint(glm::vec3 v1, glm::vec3 v2);

  /*
    Create a plane model by specified area size
    @param m reference to the plane model
    @param size the plane size
    @noreturn
  */
  virtual Model::MeshRef CreateMesh(bool generateNormalTexCoords = false) override;

  /*
    whether the point is in the plane?
    @param point the point
    @return true is in the plane, otherwise is false
  */
  bool InPlane(glm::vec3 point) const;

  /*
    Get the plane's normal
    @noparam
    @return plane's normal
  */
  glm::vec3 Normal() const;

protected:
  glm::vec3 _a; // Plane Origin
  glm::vec3 _b;
  glm::vec3 _c;
};

} // namespace Geometry
